"""处理数据层，将前端的数据传入到本层进行处理，处理过程和结果将显示在控制台界面"""
import os
from openpyxl.utils import get_column_letter
from commonData import ComData as cd
from xlrd import open_workbook

class Data:

    def __init__(self):  # 经度
        if os.path.exists(cd.folder_out) == False:
            os.mkdir(cd.folder_out)

    def get_abnormal(fun):
        def abnormal(self, *args, **kwargs):
            try:
                return fun(self, *args, **kwargs)
            except Exception as e:
                print("异常信息:{},异常方法:{}".format(e, fun.__name__))

        return abnormal  # 没有返回值

    def is_number(self, s):
        try:
            float(s)
            return True
        except ValueError:
            pass

        try:
            import unicodedata
            unicodedata.numeric(s)
            return True
        except (TypeError, ValueError):
            pass
        return False

    @get_abnormal
    def spss_to_data(self):
        """
        经过我多次测试，我发现spss输出dat文件时，数据的样子跟‘列’设置没关系，
        对于数字字母而言，它是前面加几个空格，然后在是数据；对于字符串而言，先是数据，然后在加上对应数量的空格。
        若后续数据长度大于等于所设定的宽度，那么就没有前导空格
        """
        # 输出格式，各个字段的长度、小数位数
        explain_file = cd.folder_out + '\\数据格式文件.txt'
        f_exp = open(explain_file, "w", encoding='utf-8')
        f_exp.write('名称' + ' 宽度 ' + ' 小数位数\n')
        for name, ds in cd.spss_data_format.items():
            temp = name + " " + ds[1] + " " + ds[-1] + "\n"
            f_exp.write(temp)
        for file in os.listdir(cd.folder_in):
            # 首先先把一个excel数据写入到数组中
            print("正在处理: ", file)
            # if 'xlsx' in file:
            excel = cd.folder_in + "\\" + file  # excel文件
            # if 'xlsx' in excel:
            #     wb = load_workbook(excel)
            #     sheets = wb.sheetnames
            # else:
            wb = open_workbook(excel)   # 对于xls的文件采用xlrd库读取的方式
            sheets = wb.sheet_names()   # 读取所用名字，避免重复代码
            name_letter = {}
            for name in sheets:
                # txt_name = cd.folder_out + file[:2] + "\\" + name + ".dat"  # 以sheet名作为输出名字
                txt_name = "{}\\{}{}.dat".format(cd.folder_out, file[:-5], name)
                print("写入文件: ", txt_name)
                dat_file = open(txt_name, 'w+', encoding='ANSI')
                # if 'xlsx' in excel:
                #     ws = wb[name]
                #     ws_line = ws['A1:{}1'.format(get_column_letter(ws.max_column))]
                #     line = [str(x.value) for x in ws_line[0]]
                #     low = 2
                #     max_row = ws.max_row + 1
                # else:
                ws = wb.sheet_by_name(name)
                ws_line = ws.row_values(0)   # 获取第一行的所有数据
                line = [str(x) for x in ws_line]
                low = 1  # 最低下限为1，不需要第一行的数据
                max_row = ws.nrows  # 最高
                if len(name_letter) == 0:  # 在name_letter 为空的时候，获取字母。避免重复获取
                    for k in line:
                        if k in cd.spss_data_format:
                            name_letter[k] = get_column_letter(line.index(k) + 1)
                """"数据处理"""
                # print(name_letter)
                for row in range(low, max_row):
                    temp_index = 0  # 用于记录xls格式的excel文件的下标记录
                    for n, l in name_letter.items():  # n:name , l: letter
                        data = ws.row_values(row)[temp_index]  # 同样获取一个数据
                        temp_index += 1  # 从0开始即可
                        _type = cd.spss_data_format[n][0]
                        width = int(cd.spss_data_format[n][1])
                        digit = int(cd.spss_data_format[n][2])
                        if _type == '数字':  # 0类型 1宽度 2小数位数
                            if Data.is_number(self, data) == True:  # 若是数字
                                negative_flag = 1 if float(data) < 0 else 0
                                for i in range(width - len(format(float(data), '.{}f'.format(digit))) - negative_flag):  # 减去打印出来的数量的空格, 负数也要考虑进去
                                    dat_file.write(' ')  # 打印这么多空格
                                if float(data) >= 0.0:
                                    dat_file.write(format(float(data), '.{}f'.format(digit)))  #
                                else:
                                    t = format(float(data), '.{}f'.format(digit))  # 先转为固定
                                    dat_file.write(' ')
                                    dat_file.write(str(t))
                            else:
                                for i in range(width - len(str(data)) * 2):  # 不是数字就是字符，那么也按照数字的处理方式来
                                    dat_file.write(' ')  # 打印字符长度的空格
                                dat_file.write(data)  # 然后再写入字符
                        elif _type == '字符串':  # 字符串无需打印空格
                            for i in data:
                                if data.index(i) * 2 == width:
                                    break
                                else:
                                    dat_file.write(i)
                            for i in range(width - len(str(data)) * 2):
                                dat_file.write(' ')
                    dat_file.write("\n")
